/**
 * @FileName: OrderType.java
 * @Author
 * @Description:充值缴费支付订单处理类
 * @Date 2016年3月30日 上午10:41:06
 * @CopyRight ZTE Corporation
 */
package cn.hpclub.server.controller.h5;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.aop.Before;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

import cn.dreampie.captcha.CaptchaRender;
import cn.hpclub.server.ccbpay.CcbConfig;
import cn.hpclub.server.ccbpay.CcbSubmit;
import cn.hpclub.server.ccbpay.JSEscape;
import cn.hpclub.server.ccbpay.ServiceType;
import cn.hpclub.server.constant.Constant;
import cn.hpclub.server.constant.H5ApiConstant;
import cn.hpclub.server.model.CityCounter;
import cn.hpclub.server.model.MemberOrg;
import cn.hpclub.server.model.Organization;
import cn.hpclub.server.model.RechargeOrder;
import cn.hpclub.server.service.CcbService;
import cn.hpclub.server.service.RechargeOrderService;
import cn.hpclub.server.util.DESAS;
import cn.hpclub.server.util.DateKit;
import cn.hpclub.server.util.InterfaceUtil;
import cn.hpclub.server.util.OrderType;

public class RechargeController extends BaseH5Controller{
    private static final Logger logger = LoggerFactory.getLogger(RechargeController.class);

    /**
     * @Title: genOrderId
     * @Description:生成充值缴费充值订单号，规则：1位字母+6位年月日+7位随机数（递增序列数）+2位地市编码+最多10位渠道编码， 如：
     *                                                                       C
     *                                                                       160329
     *                                                                       0000001
     *                                                                       11
     *                                                                       2
     *                                                                       void
     */
    public void genOrderId(){
        JSONObject returnObj = setResponseObj(H5ApiConstant.ResultCode.FAIL_CODE, H5ApiConstant.Msg.FAIL, null);
        String userId = getPara(H5ApiConstant.Ui.USERID, "");
        String orderId = "";
        String fxstr = "";
        JSONObject object = new JSONObject();
        try{
            if(StrKit.isBlank(userId)){
                fxstr = getPara(H5ApiConstant.Ui.FXSTR);
                if(StrKit.notBlank(fxstr)){
                    // 解码参数
                    // {"params":"11#67149#5588521#20160517204622#1405329#4001#Q1o="}
                    String fxstrDecode = getFxStrDecode(fxstr);
                    if(StrKit.notBlank(fxstrDecode)){
                        if(fxstrDecode.split("#") != null){
                            userId = fxstrDecode.split("#")[2];
                        }
                    }
                }
            }
            if(StrKit.isBlank(userId)){
                returnObj = setResponseObj(H5ApiConstant.ResultCode.FAIL_CODE,
                                           "获取订单号：" + H5ApiConstant.Msg.PARA_ILLEGAL, null);
            } else{
                MemberOrg memberInfo = MemberOrg.dao.getMemberOrgInfoByUserId(Integer.parseInt(userId));
                if(memberInfo != null){
                    String dateStr = DateKit.toStr(new Date(), "yyMMdd");
                    String cityCode = "" + memberInfo.getInt("region_id");
                    String groupId = MemberOrg.dao.getOrgNumCodebyUserid(Integer.parseInt(userId));

                    orderId = OrderType.RECHARGE.getName() + dateStr + InterfaceUtil.getOrderSeq(OrderType.RECHARGE)
                            + cityCode + groupId;

                    object.put("orgName", memberInfo.getStr("orgName"));
                    object.put("orderId", orderId);

                    if(StrKit.notBlank(fxstr)){
                        object.put("userid", memberInfo.getInt("userId"));
                    }
                    returnObj = setResponseObj(H5ApiConstant.ResultCode.SUCCESS_CODE, H5ApiConstant.Msg.EMPTY, object);
                } else{
                    returnObj = setResponseObj(H5ApiConstant.ResultCode.FAIL_CODE, H5ApiConstant.Msg.NOT_INVALID_USER,
                                               null);
                }
            }
        }
        catch(Exception e){
            e.printStackTrace();
            returnObj = setResponseObj(H5ApiConstant.ResultCode.EXCEPTION_CODE,
                                       "获取订单号：" + H5ApiConstant.Msg.SERVER_EXCEPTION, null);
        }

        renderJson(returnObj.toString());
    }

    /**
     * @Title: saveOrder
     * @Description:保存充值缴费支付订单 void
     */
    @Before(Tx.class)
    public void saveOrder(){
        JSONObject returnObj = setResponseObj(H5ApiConstant.ResultCode.FAIL_CODE, H5ApiConstant.Msg.FAIL, null);

        try{

            if(CcbService.service.timeLimit()){
                logger.info("建行支付，每天23：30-00：30不能办理该业务。请稍后办理。" + new Date());
                String msg = "建行支付，每天23：30-00：30不能办理该业务。请稍后办理。";
                JSONObject jo = setResponseObj(H5ApiConstant.ResultCode.FAIL_CODE, "订单提交失败:" + msg, msg);
                renderText(jo.toString());
                return;
            }

            // 1、保存支付订单到本地数据库
            // String captchaToken = getPara(H5ApiConstant.Ui.CAPTCHATOKEN);
            // if(!SubjectKit.doCaptcha("captcha", captchaToken.toLowerCase())){
            // logger.debug("captchaToken=" + captchaToken);
            // returnObj = setResponseObj(H5ApiConstant.ResultCode.FAIL_CODE,
            // H5ApiConstant.Msg.CAPTCHA_TOKEN_ERROR,
            // null);
            // renderText(returnObj.toString());
            // return;
            // }

            MemberOrg m = MemberOrg.dao.getMemberOrgById(getParaToLong(H5ApiConstant.Ui.USERID));

            if(m == null){
                returnObj = setResponseObj(H5ApiConstant.ResultCode.EXCEPTION_CODE, H5ApiConstant.Msg.NOT_INVALID_USER,
                                           null);
                renderText(returnObj.toString());
                return;
            }

            String orderId = getPara(H5ApiConstant.Ui.ORDERID);

            // 校验提交的订单号是不是当天生成的订单号，add by zhouxl in 2017.7.28
            if(!isCurDateOrderId(orderId)){
                returnObj = setResponseObj(H5ApiConstant.ResultCode.EXCEPTION_CODE,
                                           H5ApiConstant.Msg.NOT_CURDATE_ORDER_ID, null);
                renderText(returnObj.toString());
                return;
            }

            if(!RechargeOrder.dao.exist(orderId)){

                String orgName = Organization.dao.getOrgNameByOrgId(m.getInt(MemberOrg.ORG_ID));

                Date currDate = new Date();
                RechargeOrder rechargeOrder = new RechargeOrder();
                rechargeOrder.set(RechargeOrder.ORDER_ID, orderId);
                rechargeOrder.set(RechargeOrder.RECHARGE_PHONE, getPara(H5ApiConstant.Ui.RECHARGEPHONE));
                rechargeOrder.set(RechargeOrder.RECHARGE_MONEY,
                                  Double.valueOf(getPara(H5ApiConstant.Ui.RECHARGEMONEY, "0.00")));
                rechargeOrder.set(RechargeOrder.PAY_AMOUNT, 0.00);// 默认为未支付
                rechargeOrder.set(RechargeOrder.PAY_PLAT, getParaToInt(H5ApiConstant.Ui.PAYPLAT, 15));// 支付平台，14-支付宝，15-建设银行，16-银联
                rechargeOrder.set(RechargeOrder.USER_ID, getParaToInt(H5ApiConstant.Ui.USERID, null));
                rechargeOrder.set(RechargeOrder.SALE_TYPE, getParaToInt(H5ApiConstant.Ui.SALETYPE, null));
                rechargeOrder.set(RechargeOrder.USER_NAME, m.getStr(MemberOrg.NAME));
                rechargeOrder.set(RechargeOrder.USER_PHONE, m.getStr(MemberOrg.MOBILE));
                rechargeOrder.set(RechargeOrder.USER_ORG_ID, m.getInt(MemberOrg.ORG_ID));
                rechargeOrder.set(RechargeOrder.USER_ORG_NAME, orgName);
                rechargeOrder.set(RechargeOrder.PAY_STATUS, 0);// 支付状态(0-未支付，1-支付成功，2-支付失败)
                // rechargeOrder.set(RechargeOrder.PAY_TIME,
                // currDate);//1.6.2版本修改：创建订单时不保存支付时间，支付完成后才去更新
                rechargeOrder.set(RechargeOrder.CREATE_TIME, currDate);
                // rechargeOrder.set(RechargeOrder.IS_HANDLED, 0);
                rechargeOrder.set(RechargeOrder.OPERATED_TIME, currDate);
                rechargeOrder.set(RechargeOrder.ORDER_STATUS, 0);// 订单状态(0-未完成（未充值），5-已完成（已充值）)
                rechargeOrder.set(RechargeOrder.FXSTR, getPara(H5ApiConstant.Ui.FXSTR, null));// 回调时传参

                if(rechargeOrder.save()){
                    // 2、调用建行接口进行支付（ccbPay）
                    // 3、修改支付状态（CcbController->updateRechargeOrder）
                    // 4、调用中转服务接口进行充值（CcbController->CmccRecharge）
                    // 5、调用回调接口（充值完成后中转服务直接调用回调接口写数据到sales_promotion表）
                    Record orderRecord = RechargeOrderService.service
                            .getRechargeOrderByOrderId(rechargeOrder.getStr(RechargeOrder.ORDER_ID));

                    returnObj = setResponseObj(H5ApiConstant.ResultCode.SUCCESS_CODE, H5ApiConstant.Msg.SUCCESS,
                                               ccbPay(orderRecord));
                }
            } else{
                logger.error("*****" + orderId + "::::rechargeOrder is exist!!!");
            }
        }
        catch(Exception e){
            returnObj = setResponseObj(H5ApiConstant.ResultCode.EXCEPTION_CODE, H5ApiConstant.Msg.EXCEPTION, null);
            e.printStackTrace();
        }

        renderText(returnObj.toString());
    }

    /**
     * @Title: isCurDateOrderId
     * @Description:TODO
     * @param orderId
     * @return boolean
     */
    private boolean isCurDateOrderId(String orderId){
        if(StrKit.notBlank(orderId) && orderId.startsWith("C")){
            return DateKit.isToday(orderId.substring(1, 7));
        }

        return false;
    }

    public String ccbPay(Record orderRecord) throws Exception{

        String html = CcbSubmit.buildRequest(order2Map(orderRecord));

        logger.debug("html:" + html);

        return html;
    }

    Map<String, String> order2Map(Record orderRecord) throws Exception{

        Map<String, String> sPara = new HashMap<String, String>();

        /***************************** 以下全是必填项 ***********************************************************/

        // 这两个，根据订单userid从表里面读取对应地区的柜台ID和pub数据
        sPara.put(CcbConfig.Key.POSID, CityCounter.getPosId(orderRecord));// "861041666"
        sPara.put(CcbConfig.Key.PUB, CityCounter.getPub30(orderRecord));// "103eeaeb3af4ce00a627bc63020111"

        // 支付方式。建行填""，银联填"UnionPay"
        int payType = orderRecord.getInt(RechargeOrder.PAY_PLAT);
        logger.debug("payType:" + payType);
        if(payType == Constant.PayPlat.CCB){
            sPara.put(CcbConfig.Key.GATEWAY, CcbConfig.PayType.CCB_PAY);
        } else if(payType == Constant.PayPlat.UNION_PAY){
            sPara.put(CcbConfig.Key.GATEWAY, CcbConfig.PayType.UNION_PAY);
        }

        // 订单信息，包括订单ID，金额，订单商品名称，订单办理人姓名，都是必填项.中文要进行escape编码
        sPara.put(CcbConfig.Key.ORDERID, orderRecord.getStr(RechargeOrder.ORDER_ID));
        sPara.put(CcbConfig.Key.PAYMENT, String.valueOf(orderRecord.getDouble(RechargeOrder.RECHARGE_MONEY)));
        sPara.put(CcbConfig.Key.PROINFO, JSEscape.escape("充值缴费"));
        sPara.put(CcbConfig.Key.REGINFO, JSEscape.escape(orderRecord.getStr(RechargeOrder.USER_NAME)));

        // remark1填业务类型，1-充值缴费；2-选号入网。用于ccb支付完成后页面结果显示处根据不同业务跳转到不同的分支去。
        sPara.put(CcbConfig.Key.REMARK1, ServiceType.RECHARGE.getValue());

        return sPara;
    }

    /**
     * 参数解码
     * 
     * @Title: getFxStrDecode
     * @Description:TODO
     * @param fxstrEncode
     * @return String
     */
    private String getFxStrDecode(String fxstrEncode){
        String fxStr = "";
        try{
            DESAS desas = new DESAS();
            fxStr = desas.decrypt(fxstrEncode);
        }
        catch(Exception e){
            e.printStackTrace();
        }

        return fxStr;
    }

    /**
     * 网厅充值加密串生成
     * 
     * @Title: getFxStr
     * @Description:TODO
     * @return String
     */
    // public void getFxStr(){
    // String fxStr = "";
    // try{
    // DESAS desas = new DESAS();
    // fxStr =
    // desas.encrypt("11#67698#5568497#20160520174220#1405329#4001#Q1o=");
    // logger.debug("param_str:" + fxStr);
    // }
    // catch(Exception e){
    // e.printStackTrace();
    // }
    //
    // renderText(fxStr);
    // }

    /**
     * @Title: captcha
     * @Description:充值缴费-建行支付-获取验证码 void
     */
    public void captcha(){
        int width = 0, height = 0, minnum = 0, maxnum = 0, fontsize = 0;
        CaptchaRender captcha = new CaptchaRender();
        if(isParaExists("width")){
            width = getParaToInt("width");
        }
        if(isParaExists("height")){
            height = getParaToInt("height");
        }
        if(width > 0 && height > 0)
            captcha.setImgSize(width, height);
        if(isParaExists("minnum")){
            minnum = getParaToInt("minnum");
        }
        if(isParaExists("maxnum")){
            maxnum = getParaToInt("maxnum");
        }
        if(minnum > 0 && maxnum > 0)
            captcha.setFontNum(minnum, maxnum);
        if(isParaExists("fontsize")){
            fontsize = getParaToInt("fontsize");
        }
        if(fontsize > 0)
            captcha.setFontSize(fontsize - 2, fontsize);
        // 干扰线数量 默认0
        captcha.setLineNum(0);
        // 噪点数量 默认50
        captcha.setArtifactNum(20);
        // 使用字符 去掉0和o 避免难以确认
        captcha.setCode("123456789");
        // 验证码在session里的名字 默认 captcha,创建时间为：名字_time
        // captcha.setCaptchaName("captcha");
        // 验证码颜色 默认黑色
        // captcha.setDrawColor(new Color(255,0,0));
        // 背景干扰物颜色 默认灰
        // captcha.setDrawBgColor(new Color(0,0,0));
        // 背景色+透明度 前三位数字是rgb色，第四个数字是透明度 默认透明
        // captcha.setBgColor(new Color(225, 225, 0, 100));
        // 滤镜特效 默认随机特效 //曲面Curves //大理石纹Marble //弯折Double //颤动Wobble //扩散Diffuse
        captcha.setFilter(CaptchaRender.FilterFactory.Wobble);
        // 随机色 默认黑验证码 灰背景元素
        captcha.setRandomColor(true);
        render(captcha);
    }
}